package room

import (
	"bbs-go/internal/models"
	"bbs-go/internal/services"
	"encoding/json"
	"sync"
)

var GlobalRoom *Room

type SendBody struct {
	MessageType int    `json:"chatType"`    // 1:私聊，2:群聊
	ReceiverId  int    `json:"receiverId"`  // 好友Id，或群Id
	ContentType int    `json:"contentType"` // 消息类型,1:文本，2:图片
	Content     string `json:"content"`     // 消息内容
}

type Room struct {
	Clients   map[int]*Client
	Broadcast chan models.WsMessage
	Join      chan *Client
	Leave     chan *Client
	Mu        sync.Mutex
}

func NewRoom() *Room {
	return &Room{
		Clients:   make(map[int]*Client),
		Broadcast: make(chan models.WsMessage),
		Join:      make(chan *Client),
		Leave:     make(chan *Client),
	}
}

func (r *Room) Run() {
	for {
		select {
		case client := <-r.Join:
			r.Mu.Lock()
			r.Clients[client.UserId] = client
			r.Mu.Unlock()
		case client := <-r.Leave:
			r.Mu.Lock()
			if _, ok := r.Clients[client.UserId]; ok {
				delete(r.Clients, client.UserId)
				close(client.Send)
			}
			r.Mu.Unlock()
		case message := <-r.Broadcast:
			r.Mu.Lock()
			sendMessage, _ := json.Marshal(message)
			switch message.MessageType {
			case 1:
				friendMessage := models.FriendMessage{}
				friendMessage = message.MessageData.(models.FriendMessage)
				for _, client := range r.Clients {
					// 好友聊天
					if Contains([]int{friendMessage.ReceiverId, friendMessage.SenderId}, client.UserId) {
						select {
						case client.Send <- sendMessage:
						default:
							close(client.Send)
							delete(r.Clients, client.UserId)
						}
					}
				}
			case 2: // 群组聊天
				groupsMemberIds := make([]int, 0)
				groupMessage := models.GroupMessage{}
				groupMessage = message.MessageData.(models.GroupMessage)
				// 根据群Id获取群成员列表
				userIds, err := services.ChatGroupsMembersService.FindChatGroupsMemberIdsByGroupId(groupMessage.GroupId)
				if err != nil {
					continue
				}
				groupsMemberIds = append(groupsMemberIds, userIds...)
				for _, userId := range userIds {
					client := r.Clients[userId]
					if client != nil && Contains(groupsMemberIds, client.UserId) {
						select {
						case client.Send <- sendMessage:
						default:
							close(client.Send)
							delete(r.Clients, client.UserId)
						}
					} else if client == nil || client.UserId == 0 {
						// 数据库记录一下改用户有未读消息
						services.ChatGroupsMembersUnreadMessageService.SetUnRead(groupMessage.GroupId, userId, true)
					}
				}
			}

			r.Mu.Unlock()
		}
	}
}

func Contains(s []int, e int) bool {
	for _, a := range s {
		if a == e {
			return true
		}
	}
	return false
}
